home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / mi / mifillarc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-27  |  16.3 KB  |  761 lines

  1. /************************************************************
  2. Copyright 1989 by The Massachusetts Institute of Technology
  3.  
  4. Permission to use, copy, modify, and distribute this
  5. software and its documentation for any purpose and without
  6. fee is hereby granted, provided that the above copyright
  7. notice appear in all copies and that both that copyright
  8. notice and this permission notice appear in supporting
  9. documentation, and that the name of MIT not be used in
  10. advertising or publicity pertaining to distribution of the
  11. software without specific prior written permission.
  12. M.I.T. makes no representation about the suitability of
  13. this software for any purpose. It is provided "as is"
  14. without any express or implied warranty.
  15.  
  16. Author:  Bob Scheifler, MIT X Consortium
  17.  
  18. ********************************************************/
  19.  
  20. /* $XConsortium: mifillarc.c,v 5.10 90/02/09 10:12:04 rws Exp $ */
  21.  
  22. #include <math.h>
  23. #include "X.h"
  24. #include "Xprotostr.h"
  25. #include "miscstruct.h"
  26. #include "gcstruct.h"
  27. #include "pixmapstr.h"
  28. #include "mifpoly.h"
  29. #include "mi.h"
  30. #include "mifillarc.h"
  31.  
  32. #define QUADRANT (90 * 64)
  33. #define HALFCIRCLE (180 * 64)
  34. #define QUADRANT3 (270 * 64)
  35.  
  36. #ifndef M_PI
  37. #define M_PI    3.14159265358979323846
  38. #endif
  39.  
  40. #define Dsin(d)    sin((double)d*(M_PI/11520.0))
  41. #define Dcos(d)    cos((double)d*(M_PI/11520.0))
  42.  
  43. /* could use 64-bit integers */
  44. typedef struct _miFillArcD {
  45.     int xorg, yorg;
  46.     int y;
  47.     int dx, dy;
  48.     double e, ex;
  49.     double ym, yk, xm, xk;
  50. } miFillArcDRec;
  51.  
  52. void
  53. miFillArcSetup(arc, info)
  54.     register xArc *arc;
  55.     register miFillArcRec *info;
  56. {
  57.     if (arc->width == arc->height)
  58.     {
  59.     /* (2x - 2xorg)^2 = d^2 - (2y - 2yorg)^2 */
  60.     /* even: xorg = yorg = 0   odd:  xorg = .5, yorg = -.5 */
  61.     info->ym = 8;
  62.     info->xm = 8;
  63.     info->y = arc->width >> 1;
  64.     info->dy = arc->width & 1;
  65.     info->yorg = arc->y + info->y;
  66.     info->xorg = arc->x + info->y + info->dy;
  67.     info->dx = 1 - info->dy;
  68.     if (arc->width & 1)
  69.     {
  70.         info->e = -1;
  71.         info->xk = 0;
  72.     }
  73.     else
  74.     {
  75.         info->y++;
  76.         info->e = - (info->y << 3);
  77.         info->xk = 4;
  78.     }
  79.     info->ex = -info->xk;
  80.     info->yk = info->xk;
  81.     }
  82.     else
  83.     {
  84.     /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
  85.     /* even: xorg = yorg = 0   odd:  xorg = .5, yorg = -.5 */
  86.     info->ym = (arc->width * arc->width) << 3;
  87.     info->xm = (arc->height * arc->height) << 3;
  88.     info->y = arc->height >> 1;
  89.     info->yorg = arc->y + info->y;
  90.     info->dy = arc->height & 1;
  91.     info->dx = arc->width & 1;
  92.     info->xorg = arc->x + (arc->width >> 1) + info->dx;
  93.     info->dx = 1 - info->dx;
  94.     if (arc->height & 1)
  95.         info->yk = 0;
  96.     else
  97.         info->yk = info->ym >> 1;
  98.     if (arc->width & 1)
  99.     {
  100.         info->xk = 0;
  101.         info->e = - (info->xm >> 3);
  102.     }
  103.     else
  104.     {
  105.         info->y++;
  106.         info->xk = info->xm >> 1;
  107.         info->e = info->yk - (info->ym * info->y) - info->xk;
  108.     }
  109.     info->ex = -info->xk;
  110.     }
  111. }
  112.  
  113. static void
  114. miFillArcDSetup(arc, info)
  115.     register xArc *arc;
  116.     register miFillArcDRec *info;
  117. {
  118.     /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
  119.     /* even: xorg = yorg = 0   odd:  xorg = .5, yorg = -.5 */
  120.     info->ym = ((double)arc->width) * (arc->width * 8);
  121.     info->xm = ((double)arc->height) * (arc->height * 8);
  122.     info->y = arc->height >> 1;
  123.     info->yorg = arc->y + info->y;
  124.     info->dy = arc->height & 1;
  125.     info->dx = arc->width & 1;
  126.     info->xorg = arc->x + (arc->width >> 1) + info->dx;
  127.     info->dx = 1 - info->dx;
  128.     if (arc->height & 1)
  129.     info->yk = 0.0;
  130.     else
  131.     info->yk = info->ym / 2.0;
  132.     if (arc->width & 1)
  133.     {
  134.     info->xk = 0;
  135.     info->e = - (info->xm / 8.0);
  136.     }
  137.     else
  138.     {
  139.     info->y++;
  140.     info->xk = info->xm / 2.0;
  141.     info->e = info->yk - (info->ym * info->y) - info->xk;
  142.     }
  143.     info->ex = -info->xk;
  144. }
  145.  
  146. static void
  147. miGetArcEdge(arc, edge, k, top, left)
  148.     register xArc *arc;
  149.     register miSliceEdgePtr edge;
  150.     int k;
  151.     Bool top, left;
  152. {
  153.     register int xady, y;
  154.  
  155.     y = arc->height >> 1;
  156.     if (!(arc->width & 1))
  157.     y++;
  158.     if (!top)
  159.     {
  160.     y = -y;
  161.     if (arc->height & 1)
  162.         y--;
  163.     }
  164.     xady = k + y * edge->dx;
  165.     if (xady <= 0)
  166.     edge->x = - ((-xady) / edge->dy + 1);
  167.     else
  168.     edge->x = (xady - 1) / edge->dy;
  169.     edge->e = xady - edge->x * edge->dy;
  170.     if ((top && (edge->dx < 0)) || (!top && (edge->dx > 0)))
  171.     edge->e = edge->dy - edge->e + 1;
  172.     if (left)
  173.     edge->x++;
  174.     edge->x += arc->x + (arc->width >> 1);
  175.     if (edge->dx > 0)
  176.     {
  177.     edge->deltax = 1;
  178.     edge->stepx = edge->dx / edge->dy;
  179.     edge->dx = edge->dx % edge->dy;
  180.     }
  181.     else
  182.     {
  183.     edge->deltax = -1;
  184.     edge->stepx = - ((-edge->dx) / edge->dy);
  185.     edge->dx = (-edge->dx) % edge->dy;
  186.     }
  187.     if (!top)
  188.     {
  189.     edge->deltax = -edge->deltax;
  190.     edge->stepx = -edge->stepx;
  191.     }
  192. }
  193.  
  194. static void
  195. miGetPieEdge(arc, angle, edge, top, left)
  196.     register xArc *arc;
  197.     register int angle;
  198.     register miSliceEdgePtr edge;
  199.     Bool top, left;
  200. {
  201.     register int k, signdx, signdy;
  202.     double dx, dy, scale;
  203.  
  204.     if ((angle == 0) || (angle == HALFCIRCLE))
  205.     {
  206.     horz:
  207.     edge->x = left ? -65536 : 65536;
  208.     edge->stepx = 0;
  209.     edge->e = 0;
  210.     edge->dx = -1;
  211.     return;
  212.     }
  213.     if ((angle == QUADRANT) || (angle == QUADRANT3))
  214.     {
  215.     vert:
  216.     edge->x = arc->x + (arc->width >> 1);
  217.     if (left && (arc->width & 1))
  218.         edge->x++;
  219.     else if (!left && !(arc->width & 1))
  220.         edge->x--;
  221.     edge->stepx = 0;
  222.     edge->e = 0;
  223.     edge->dx = -1;
  224.     return;
  225.     }
  226.     dy = Dsin(angle) * arc->height;
  227.     if (dy < 0.0)
  228.     {
  229.     dy = -dy;
  230.     signdy = -1;
  231.     }
  232.     else
  233.     signdy = 1;
  234.     dx = Dcos(angle) * arc->width;
  235.     if (dx < 0.0)
  236.     {
  237.     dx = -dx;
  238.     signdx = -1;
  239.     }
  240.     else
  241.     signdx = 1;
  242.     scale = (dx > dy) ? dx : dy;
  243.     edge->dx = floor((dx * 32768) / scale + .5);
  244.     if (!edge->dx) goto vert; /* gross */
  245.     edge->dy = floor((dy * 32768) / scale + .5);
  246.     if (!edge->dy) goto horz; /* gross */
  247.     if (signdx < 0)
  248.     edge->dx = -edge->dx;
  249.     if (signdy < 0)
  250.     edge->dx = -edge->dx;
  251.     k = (arc->height & 1) ? edge->dx : 0;
  252.     if (arc->width & 1)
  253.     k += edge->dy;
  254.     edge->dx <<= 1;
  255.     edge->dy <<= 1;
  256.     miGetArcEdge(arc, edge, k, top, left);
  257. }
  258.  
  259. void
  260. miFillArcSliceSetup(arc, slice, pGC)
  261.     register xArc *arc;
  262.     register miArcSliceRec *slice;
  263.     GCPtr pGC;
  264. {
  265.     register int angle1, angle2;
  266.  
  267.     angle1 = arc->angle1;
  268.     if (arc->angle2 < 0)
  269.     {
  270.     angle2 = angle1;
  271.     angle1 += arc->angle2;
  272.     }
  273.     else
  274.     angle2 = angle1 + arc->angle2;
  275.     while (angle1 < 0)
  276.     angle1 += FULLCIRCLE;
  277.     while (angle1 >= FULLCIRCLE)
  278.     angle1 -= FULLCIRCLE;
  279.     while (angle2 < 0)
  280.     angle2 += FULLCIRCLE;
  281.     while (angle2 >= FULLCIRCLE)
  282.     angle2 -= FULLCIRCLE;
  283.     slice->min_top_y = 0;
  284.     slice->max_top_y = arc->height >> 1;
  285.     slice->min_bot_y = 1 - (arc->height & 1);
  286.     slice->max_bot_y = slice->max_top_y - 1;
  287.     slice->flip_top = FALSE;
  288.     slice->flip_bot = FALSE;
  289.     if (pGC->arcMode == ArcPieSlice)
  290.     {
  291.     slice->edge1_top = (angle1 < HALFCIRCLE);
  292.     slice->edge2_top = (angle2 <= HALFCIRCLE);
  293.     if ((angle2 == 0) || (angle1 == HALFCIRCLE))
  294.     {
  295.         if (angle2 ? slice->edge2_top : slice->edge1_top)
  296.         slice->min_top_y = slice->min_bot_y;
  297.         else
  298.         slice->min_top_y = arc->height;
  299.         slice->min_bot_y = 0;
  300.     }
  301.     else if ((angle1 == 0) || (angle2 == HALFCIRCLE))
  302.     {
  303.         slice->min_top_y = slice->min_bot_y;
  304.         if (angle1 ? slice->edge1_top : slice->edge2_top)
  305.         slice->min_bot_y = arc->height;
  306.         else
  307.         slice->min_bot_y = 0;
  308.     }
  309.     else if (slice->edge1_top == slice->edge2_top)
  310.     {
  311.         if (angle2 < angle1)
  312.         {
  313.         slice->flip_top = slice->edge1_top;
  314.         slice->flip_bot = !slice->edge1_top;
  315.         }
  316.         else if (slice->edge1_top)
  317.         {
  318.         slice->min_top_y = 1;
  319.         slice->min_bot_y = arc->height;
  320.         }
  321.         else
  322.         {
  323.         slice->min_bot_y = 0;
  324.         slice->min_top_y = arc->height;
  325.         }
  326.     }
  327.     miGetPieEdge(arc, angle1, &slice->edge1,
  328.              slice->edge1_top, !slice->edge1_top);
  329.     miGetPieEdge(arc, angle2, &slice->edge2,
  330.              slice->edge2_top, slice->edge2_top);
  331.     }
  332.     else
  333.     {
  334.     double w2, h2, x1, y1, dx, dy, scale;
  335.     int signdx, signdy, y, k;
  336.  
  337.     w2 = (double)arc->width / 2.0;
  338.     h2 = (double)arc->height / 2.0;
  339.     if ((angle1 == 0) || (angle1 == HALFCIRCLE))
  340.     {
  341.         x1 = angle1 ? -w2 : w2;
  342.         y1 = 0.0;
  343.     }
  344.     else if ((angle1 == QUADRANT) || (angle1 == QUADRANT3))
  345.     {
  346.         x1 = 0.0;
  347.         y1 = (angle1 == QUADRANT) ? h2 : -h2;
  348.     }
  349.     else
  350.     {
  351.         x1 = Dcos(angle1) * w2;
  352.         y1 = Dsin(angle1) * h2;
  353.     }
  354.     if ((angle2 == 0) || (angle2 == HALFCIRCLE))
  355.     {
  356.         dx = angle2 ? -w2 : w2;
  357.         dy = 0.0;
  358.     }
  359.     else if ((angle2 == QUADRANT) || (angle2 == QUADRANT3))
  360.     {
  361.         dx = 0.0;
  362.         dy = (angle2 == QUADRANT) ? h2 : -h2;
  363.     }
  364.     else
  365.     {
  366.         dx = Dcos(angle2) * w2;
  367.         dy = Dsin(angle2) * h2;
  368.     }
  369.     dx -= x1;
  370.     dy -= y1;
  371.     if (arc->height & 1)
  372.         y1 -= 0.5;
  373.     if (arc->width & 1)
  374.         x1 += 0.5;
  375.     if (dy < 0.0)
  376.     {
  377.         dy = -dy;
  378.         signdy = -1;
  379.     }
  380.     else
  381.         signdy = 1;
  382.     if (dx < 0.0)
  383.     {
  384.         dx = -dx;
  385.         signdx = -1;
  386.     }
  387.     else
  388.         signdx = 1;
  389.     scale = (dx > dy) ? dx : dy;
  390.     slice->edge1.dx = floor((dx * 32768) / scale + .5);
  391.     slice->edge1.dy = floor((dy * 32768) / scale + .5);
  392.     if (!slice->edge1.dy)
  393.     {
  394.         if (signdx < 0)
  395.         {
  396.         y = floor(y1 + 1.0);
  397.         if (y >= 0)
  398.         {
  399.             slice->min_top_y = y;
  400.             slice->min_bot_y = arc->height;
  401.         }
  402.         else
  403.         {
  404.             slice->max_bot_y = -y - (arc->height & 1);
  405.         }
  406.         }
  407.         else
  408.         {
  409.         y = floor(y1);
  410.         if (y >= 0)
  411.             slice->max_top_y = y;
  412.         else
  413.         {
  414.             slice->min_top_y = arc->height;
  415.             slice->min_bot_y = -y - (arc->height & 1);
  416.         }
  417.         }
  418.         slice->edge1_top = TRUE;
  419.         slice->edge1.x = 65536;
  420.         slice->edge1.stepx = 0;
  421.         slice->edge1.e = 0;
  422.         slice->edge1.dx = -1;
  423.         slice->edge2 = slice->edge1;
  424.         slice->edge2_top = FALSE;
  425.     }
  426.     else if (!slice->edge1.dx)
  427.     {
  428.         if (signdy < 0)
  429.         x1 -= 1.0;
  430.         slice->edge1.x = ceil(x1);
  431.         slice->edge1_top = signdy < 0;
  432.         slice->edge1.x += arc->x + (arc->width >> 1);
  433.         slice->edge1.stepx = 0;
  434.         slice->edge1.e = 0;
  435.         slice->edge1.dx = -1;
  436.         slice->edge2_top = !slice->edge1_top;
  437.         slice->edge2 = slice->edge1;
  438.     }
  439.     else
  440.     {
  441.         if (signdx < 0)
  442.         slice->edge1.dx = -slice->edge1.dx;
  443.         if (signdy < 0)
  444.         slice->edge1.dx = -slice->edge1.dx;
  445.         k = ceil(x1 * slice->edge1.dy - y1 * slice->edge1.dx);
  446.         slice->edge2.dx = slice->edge1.dx;
  447.         slice->edge2.dy = slice->edge1.dy;
  448.         slice->edge1_top = signdy < 0;
  449.         slice->edge2_top = !slice->edge1_top;
  450.         miGetArcEdge(arc, &slice->edge1, k,
  451.              slice->edge1_top, !slice->edge1_top);
  452.         miGetArcEdge(arc, &slice->edge2, k,
  453.              slice->edge2_top, slice->edge2_top);
  454.     }
  455.     }
  456. }
  457.  
  458. #define ADDSPANS() \
  459.     pts->x = xorg - x; \
  460.     pts->y = yorg - y; \
  461.     *wids = slw; \
  462.     pts++; \
  463.     wids++; \
  464.     if (miFillArcLower(slw)) \
  465.     { \
  466.     pts->x = xorg - x; \
  467.     pts->y = yorg + y + dy; \
  468.     pts++; \
  469.     *wids++ = slw; \
  470.     }
  471.  
  472. static void
  473. miFillEllipseI(pDraw, pGC, arc)
  474.     DrawablePtr pDraw;
  475.     GCPtr pGC;
  476.     xArc *arc;
  477. {
  478.     register int x, y, e, ex;
  479.     int yk, xk, ym, xm, dx, dy, xorg, yorg;
  480.     int slw;
  481.     miFillArcRec info;
  482.     DDXPointPtr points;
  483.     register DDXPointPtr pts;
  484.     int *widths;
  485.     register int *wids;
  486.  
  487.     points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * arc->height);
  488.     if (!points)
  489.     return;
  490.     widths = (int *)ALLOCATE_LOCAL(sizeof(int) * arc->height);
  491.     if (!widths)
  492.     {
  493.     DEALLOCATE_LOCAL(points);
  494.     return;
  495.     }
  496.     miFillArcSetup(arc, &info);
  497.     MIFILLARCSETUP();
  498.     if (pGC->miTranslate)
  499.     {
  500.     xorg += pDraw->x;
  501.     yorg += pDraw->y;
  502.     }
  503.     pts = points;
  504.     wids = widths;
  505.     if (arc->width == arc->height)
  506.     {
  507.     while (y)
  508.     {
  509.         MIFILLCIRCSTEP(slw);
  510.         ADDSPANS();
  511.     }
  512.     }
  513.     else
  514.     {
  515.     while (y > 0)
  516.     {
  517.         MIFILLELLSTEP(slw);
  518.         ADDSPANS();
  519.     }
  520.     }
  521.     (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
  522.     DEALLOCATE_LOCAL(widths);
  523.     DEALLOCATE_LOCAL(points);
  524. }
  525.  
  526. static void
  527. miFillEllipseD(pDraw, pGC, arc)
  528.     DrawablePtr pDraw;
  529.     GCPtr pGC;
  530.     xArc *arc;
  531. {
  532.     register int x, y;
  533.     int xorg, yorg, dx, dy, slw;
  534.     double e, yk, xk, ym, xm, ex;
  535.     miFillArcDRec info;
  536.     DDXPointPtr points;
  537.     register DDXPointPtr pts;
  538.     int *widths;
  539.     register int *wids;
  540.  
  541.     points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * arc->height);
  542.     if (!points)
  543.     return;
  544.     widths = (int *)ALLOCATE_LOCAL(sizeof(int) * arc->height);
  545.     if (!widths)
  546.     {
  547.     DEALLOCATE_LOCAL(points);
  548.     return;
  549.     }
  550.     miFillArcDSetup(arc, &info);
  551.     MIFILLARCSETUP();
  552.     if (pGC->miTranslate)
  553.     {
  554.     xorg += pDraw->x;
  555.     yorg += pDraw->y;
  556.     }
  557.     pts = points;
  558.     wids = widths;
  559.     while (y > 0)
  560.     {
  561.     MIFILLELLSTEP(slw);
  562.     ADDSPANS();
  563.     }
  564.     (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
  565.     DEALLOCATE_LOCAL(widths);
  566.     DEALLOCATE_LOCAL(points);
  567. }
  568.  
  569. #define ADDSPAN(l,r) \
  570.     if (r >= l) \
  571.     { \
  572.     pts->x = l; \
  573.     pts->y = ya; \
  574.     pts++; \
  575.     *wids++ = r - l + 1; \
  576.     }
  577.  
  578. #define ADDSLICESPANS(flip) \
  579.     if (!flip) \
  580.     { \
  581.     ADDSPAN(xl, xr); \
  582.     } \
  583.     else \
  584.     { \
  585.     xc = xorg - x; \
  586.     ADDSPAN(xc, xr); \
  587.     xc += slw - 1; \
  588.     ADDSPAN(xl, xc); \
  589.     }
  590.  
  591. static void
  592. miFillArcSliceI(pDraw, pGC, arc)
  593.     DrawablePtr pDraw;
  594.     GCPtr pGC;
  595.     xArc *arc;
  596. {
  597.     int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
  598.     register int x, y, e, ex;
  599.     miFillArcRec info;
  600.     miArcSliceRec slice;
  601.     int ya, xl, xr, xc;
  602.     int iscircle;
  603.     DDXPointPtr points;
  604.     register DDXPointPtr pts;
  605.     int *widths;
  606.     register int *wids;
  607.  
  608.     miFillArcSetup(arc, &info);
  609.     miFillArcSliceSetup(arc, &slice, pGC);
  610.     MIFILLARCSETUP();
  611.     slw = arc->height;
  612.     if (slice.flip_top || slice.flip_bot)
  613.     slw += (arc->height >> 1) + 1;
  614.     points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * slw);
  615.     if (!points)
  616.     return;
  617.     widths = (int *)ALLOCATE_LOCAL(sizeof(int) * slw);
  618.     if (!widths)
  619.     {
  620.     DEALLOCATE_LOCAL(points);
  621.     return;
  622.     }
  623.     iscircle = (arc->width == arc->height);
  624.     if (pGC->miTranslate)
  625.     {
  626.     xorg += pDraw->x;
  627.     yorg += pDraw->y;
  628.     slice.edge1.x += pDraw->x;
  629.     slice.edge2.x += pDraw->x;
  630.     }
  631.     pts = points;
  632.     wids = widths;
  633.     while (y > 0)
  634.     {
  635.     if (iscircle)
  636.     {
  637.         MIFILLCIRCSTEP(slw);
  638.     }
  639.     else
  640.     {
  641.         MIFILLELLSTEP(slw);
  642.     }
  643.     MIARCSLICESTEP(slice.edge1);
  644.     MIARCSLICESTEP(slice.edge2);
  645.     if (miFillSliceUpper(slice))
  646.     {
  647.         ya = yorg - y;
  648.         MIARCSLICEUPPER(xl, xr, slice, slw);
  649.         ADDSLICESPANS(slice.flip_top);
  650.     }
  651.     if (miFillSliceLower(slice))
  652.     {
  653.         ya = yorg + y + dy;
  654.         MIARCSLICELOWER(xl, xr, slice, slw);
  655.         ADDSLICESPANS(slice.flip_bot);
  656.     }
  657.     }
  658.     (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
  659.     DEALLOCATE_LOCAL(widths);
  660.     DEALLOCATE_LOCAL(points);
  661. }
  662.  
  663. static void
  664. miFillArcSliceD(pDraw, pGC, arc)
  665.     DrawablePtr pDraw;
  666.     GCPtr pGC;
  667.     xArc *arc;
  668. {
  669.     register int x, y;
  670.     int dx, dy, xorg, yorg, slw;
  671.     double e, yk, xk, ym, xm, ex;
  672.     miFillArcDRec info;
  673.     miArcSliceRec slice;
  674.     int ya, xl, xr, xc;
  675.     DDXPointPtr points;
  676.     register DDXPointPtr pts;
  677.     int *widths;
  678.     register int *wids;
  679.  
  680.     miFillArcDSetup(arc, &info);
  681.     miFillArcSliceSetup(arc, &slice, pGC);
  682.     MIFILLARCSETUP();
  683.     slw = arc->height;
  684.     if (slice.flip_top || slice.flip_bot)
  685.     slw += (arc->height >> 1) + 1;
  686.     points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * slw);
  687.     if (!points)
  688.     return;
  689.     widths = (int *)ALLOCATE_LOCAL(sizeof(int) * slw);
  690.     if (!widths)
  691.     {
  692.     DEALLOCATE_LOCAL(points);
  693.     return;
  694.     }
  695.     if (pGC->miTranslate)
  696.     {
  697.     xorg += pDraw->x;
  698.     yorg += pDraw->y;
  699.     slice.edge1.x += pDraw->x;
  700.     slice.edge2.x += pDraw->x;
  701.     }
  702.     pts = points;
  703.     wids = widths;
  704.     while (y > 0)
  705.     {
  706.     MIFILLELLSTEP(slw);
  707.     MIARCSLICESTEP(slice.edge1);
  708.     MIARCSLICESTEP(slice.edge2);
  709.     if (miFillSliceUpper(slice))
  710.     {
  711.         ya = yorg - y;
  712.         MIARCSLICEUPPER(xl, xr, slice, slw);
  713.         ADDSLICESPANS(slice.flip_top);
  714.     }
  715.     if (miFillSliceLower(slice))
  716.     {
  717.         ya = yorg + y + dy;
  718.         MIARCSLICELOWER(xl, xr, slice, slw);
  719.         ADDSLICESPANS(slice.flip_bot);
  720.     }
  721.     }
  722.     (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
  723.     DEALLOCATE_LOCAL(widths);
  724.     DEALLOCATE_LOCAL(points);
  725. }
  726.  
  727. /* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
  728.  * Since we don't have to worry about overlapping segments, we can just
  729.  * fill each arc as it comes.
  730.  */
  731. void
  732. miPolyFillArc(pDraw, pGC, narcs, parcs)
  733.     DrawablePtr    pDraw;
  734.     GCPtr    pGC;
  735.     int        narcs;
  736.     xArc    *parcs;
  737. {
  738.     register int i;
  739.     register xArc *arc;
  740.  
  741.     for(i = narcs, arc = parcs; --i >= 0; arc++)
  742.     {
  743.     if (miFillArcEmpty(arc))
  744.         continue;;
  745.     if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
  746.     {
  747.         if (miCanFillArc(arc))
  748.         miFillEllipseI(pDraw, pGC, arc);
  749.         else
  750.         miFillEllipseD(pDraw, pGC, arc);
  751.     }
  752.     else
  753.     {
  754.         if (miCanFillArc(arc))
  755.         miFillArcSliceI(pDraw, pGC, arc);
  756.         else
  757.         miFillArcSliceD(pDraw, pGC, arc);
  758.     }
  759.     }
  760. }
  761.